package com.kgd.news.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jfinal.core.Const;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.IAtom;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.ehcache.CacheKit;
import com.kgd.news.bean.VideoInfoModel;
import com.kgd.news.entity.*;
import com.kgd.news.utils.*;
import com.kgd.news.utils.cache.CacheUtils;
import com.kgd.news.utils.cache.DbCacheFindUtls;
import com.kgd.news.utils.wx.VideoHelper;
import com.kgd.news.utils.wx.WxHelper;
import com.kgd.news.wxpay.constant.Constant;
import com.kgd.news.wxpay.controller.PayControllerUtil;
import com.kgd.news.wxpay.controller.TransferController;
import com.kgd.news.wxpay.entity.PayInfo;
import com.kgd.news.wxpay.util.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.log4j.Logger;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.lang.reflect.Method;
import java.security.*;
import java.security.spec.InvalidParameterSpecException;
import java.sql.SQLException;
import java.util.*;
import java.util.regex.Pattern;

import static com.kgd.news.utils.Api.D_204;

/**
 * @Email: huangsanm@foxmail.com
 * @Date: 2017/9/24
 * @Time: 下午4:10
 */
public class IndexController extends ApiController {
    private static Logger log = Logger.getLogger(IndexController.class);

    /**
     * 获取微信openid
     */
    public void getOpenUserId() {
        String code = getPara("wx_code");
        String result = WxHelper.requestWxOpenId(code);
        if (!StringUtilsWx.isEmpty(result)) {
            JSONObject data = JSONObject.parseObject(result);
            renderJson(new Api(data).get());
        } else {
            renderJson(new Api(Api.E_201, null).get());
        }
    }

    public void test() {
        Image image = new Image();
        image.setRealurl("https://v.qq.com/x/page/f0505lwxwa7.html");

        VideoHelper.transUrlTovalid(image);
    }

    /**
     * 获取微信openid,微信规定
     */
    public void decodeUserInfo() {

        String encryptedData = getPara("encryptedData");
        encryptedData = encryptedData.replace(" ", "+");
        String session_key = getPara("session_key");
        session_key = session_key.replace(" ", "+");
//        String aesKey = StringUtils.decodeByBase64(session_key);
        String iv = getPara("iv");
        iv = iv.replace(" ", "+");

//        getUserInfo(encryptedData1,session_key1,iv1);
        try {
//            String encryptedData = "+lVEkrSy7TeIUyXEcoaOEHZH4Lggvx63p+3RxGftRsY4JizAHCj4SBrvtMM25ZWLPg7GiJ0jEZFc4CVsC8OjZnWMKHrobwn79Yyk4Cwarz7uJfRU6VKAeYyWgYMjOf9tNaC9nyS12INp/SIaYrv3cA==";
//            String session_key = "Ky26I8q35bb+SBb6xZCNmg==";
//        String aesKey = StringUtils.decodeByBase64(session_key);
//            String iv = "kh/VxJhrQOezHmGooS4gag==";

            byte[] dataByte = decodeBase64(encryptedData);
            byte[] keyByte = decodeBase64(session_key);
            byte[] ivByte = decodeBase64(iv);
//      iv = "kh/VxJhrQOezHmGooS4gag==";
//            Base64 base64 = new Base64();
//            base64.decode(encryptedData);
            // 如果密钥不足16位，那么就补足.  这个if 中的内容很重要
            int base = 16;
            if (keyByte.length % base != 0) {
                int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
                byte[] temp = new byte[groups * base];
                Arrays.fill(temp, (byte) 0);
                System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
                keyByte = temp;
            }
            // 初始化
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
            SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
            AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
            parameters.init(new IvParameterSpec(ivByte));
            cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
            byte[] resultByte = cipher.doFinal(dataByte);
            if (null != resultByte && resultByte.length > 0) {
                String result = new String(resultByte, "UTF-8");
                JSONObject data = JSONObject.parseObject(result);
                renderJson(new Api(data).get());
            } else {
                renderJson(new Api(Api.E_201, null).get());
            }
            return;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidParameterSpecException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        renderJson(new Api(Api.E_201, null).get());
    }

    /***
     * decode by Base64
     */
    public static byte[] decodeBase64(String input) throws Exception {
        Class clazz = Class.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");
        Method mainMethod = clazz.getMethod("decode", String.class);
        mainMethod.setAccessible(true);
        Object retObj = mainMethod.invoke(null, input);
        return (byte[]) retObj;
    }

    /**
     * 用户登录
     */
    public void login() {
        String from = getPara("froms");
        if (StringUtilsWx.isEmpty(from)) {
            renderJson(new Api(D_204, "参数错误").get());
            return;
        }
        String userid = getPara("userid");//openid
        if (StringUtilsWx.isEmpty(userid)) {
            renderJson(new Api(D_204, "参数错误").get());
            return;
        }
        SysUser user = SysUser.dao.findFirst("select * from sys_user where userid = ?", userid);
        if (user != null) {
            if (user.getStatus() == 2) {
                renderJson(new Api(Api.L_206, null, "用户已被冻结"));
            } else {
                renderJson(new Api(user).get());
            }
            return;
        }
        String logo = getPara("logo");// 头像
        int sex = getParaToInt("sex");//1男，0女
        String name = getPara("name");//微信昵称
        String address = getPara("address");//地址
        user = new SysUser();
        user.setSname(name);
        user.setCreatetime(DateUtils.getCurDate());
        user.setSex(sex);
        user.setAddress(address);
        user.setLogo(logo);
        user.setUserid(userid);
        user.setFroms(from);
        if (user.save()) {
            renderJson(new Api(user, "登录成功").get());
        } else {
            renderJson(new Api(Api.E_201, "登录失败").get());
        }
    }

    /**
     * 获取系统设置
     */
    public void getSettings() {
        List<SysSettings> object = CacheKit.get("cache", "setting");
        if (object != null) {
        } else {
            object = SysSettings.dao.find("select * from sys_settings");
            CacheKit.put("cache", "setting", object);
        }
        renderJson(new Api(object).get());
    }

    /**
     * 获取类别
     */
    public void getCategoryList() {
        String parentid = getPara("categoryid");
        List<Category> list = CacheKit.get("category", "category" + parentid);
        if (list != null && list.size() > 0) {
        } else {
            list = Category.dao.find("select * from category where parentid = ? order by corder desc", parentid);
            CacheKit.put("category", "category" + parentid, list);
        }
        renderJson(new Api(list).get());
    }

    /**
     * 获取资讯列表
     */
    public void getNewsList() {
        String sql = "from news where 1=1 ";
        String cateogryid = getPara("categoryid");
        String title = getPara("title");
        JSONObject json = CacheKit.get("news", "news" + title + cateogryid + getPageIndex());
        if (json != null) {
        } else {
            if (!StringUtilsWx.isEmpty(cateogryid) && !"-1".equals(cateogryid)) {
                sql += " and categoryid = " + cateogryid;
            }
            if (!StringUtilsWx.isEmpty(title)) {
                sql += " and title like '%" + title + "%'";
            }
            String sql1 = sql;
            sql += " and isbanner = 2 ";
            if ("-1".equals(cateogryid)) {
                sql += " order by readtimes desc";
            } else {
                sql += "order by id desc";
            }
            Page<News> data = News.dao.paginate(getPageIndex(), PAGE_SIZE, "select *", sql);
            //List<News> list = News.dao.find(sql);
            json = new JSONObject();
            json.put("newsList", data.getList());
            json.put("pageIndex", data.getPageNumber());
            json.put("pageCount", data.getTotalPage());
            json.put("isLastPage", data.isLastPage());
            //获取推荐列表
            sql1 = "select * " + sql1 + " and isbanner = 1 order by id desc limit 0, 2";
            List<News> list1 = News.dao.find(sql1);
            json.put("bannerList", list1);
            CacheKit.put("news", "news" + title + cateogryid + getPageIndex(), json);
        }
        renderJson(new Api(Api.S_200, json).get());
    }

    /**
     * 资讯详情
     */
    public void getNewsDetail() {
        String newsId = getPara("newsid");
        Integer genderInt = getParaToInt("gender");
        News news = News.dao.findById(newsId);
        String xtype = getPara("xtype");
        if (StringUtilsWx.isEmpty(xtype)) {
            news.setReadtimes(news.getReadtimes() + 1);
            news.update();
        }
        String url = news.getVideourl();
        if (url == null || url.isEmpty()) {
            if (!StringUtilsWx.isEmpty(news.getVideorealurl())) {
                VideoHelper.transUrlTovalid(news);
            }
        } else {
            if (url.endsWith("mp4")) {
            } else {
                String updateurltime = news.getUpdateurltime();
                if (updateurltime == null || updateurltime.isEmpty()) {
                    VideoHelper.transUrlTovalid(news);
                } else {
//                    配置文件配置
                    // TODO: 2017/11/21
                    boolean isVideoOutOfTime = DateUtils.isOutOfTime(updateurltime, 4 * 60);
                    if (isVideoOutOfTime) {
                        VideoHelper.transUrlTovalid(news);
                    }
                }
            }
        }
        JSONObject object = CacheKit.get("news", "newsdetail" + newsId + genderInt + getPageIndex());
        if (object != null) {
        } else {
            object = new JSONObject();
            object.put("news", news);
            Page<Comment> data = Comment.dao.paginate(getPageIndex(), PAGE_SIZE, "select *", "from comment where otherid = ?", newsId);
            object.put("comments", data.getList());
            object.put("pageIndex", data.getPageNumber());
            object.put("isLastPage", data.isLastPage());
            String sql = "select * from news where categoryid = ? and id <> " + newsId + " order by id desc limit 0, 2";
            List<News> newsList = News.dao.find(sql, news.getCategoryid());
            object.put("newsList", newsList);
            if (genderInt == null) {
                object.put("adv", Adv.dao.findFirst("select * from adv where categoryid = ? ", news.getCategoryid()));
            } else {
                object.put("adv", Adv.dao.findFirst("select * from adv where categoryid = ? and gender = ?", news.getCategoryid(), genderInt));
            }
            CacheKit.put("news", "newsdetail" + newsId + genderInt + getPageIndex(), object);
        }
        renderJson(new Api(object).get());
    }


    /**
     * 资讯详情
     */
    public void getNewsDetailForce() {
        String newsId = getPara("newsid");
        Integer genderInt = getParaToInt("gender");
        News news = News.dao.findById(newsId);
        String xtype = getPara("xtype");
        if (StringUtilsWx.isEmpty(xtype)) {
            news.setReadtimes(news.getReadtimes() + 1);
            news.update();
        }
        String url = news.getVideourl();
        if (url == null || url.isEmpty()) {
        } else {
            if (url.endsWith("mp4")) {
            } else {
                VideoHelper.transUrlTovalid(news);
            }
        }
        JSONObject object = CacheKit.get("news", "newsdetail" + newsId + genderInt + getPageIndex());
        if (object != null) {
        } else {
            object = new JSONObject();
            object.put("news", news);
            Page<Comment> data = Comment.dao.paginate(getPageIndex(), PAGE_SIZE, "select *", "from comment where otherid = ?", newsId);
            object.put("comments", data.getList());
            object.put("pageIndex", data.getPageNumber());
            object.put("isLastPage", data.isLastPage());
            String sql = "select * from news where categoryid = ? and id <> " + newsId + " order by id desc limit 0, 2";
            List<News> newsList = News.dao.find(sql, news.getCategoryid());
            object.put("newsList", newsList);
            if (genderInt == null) {
                object.put("adv", Adv.dao.findFirst("select * from adv where categoryid = ? ", news.getCategoryid()));
            } else {
                object.put("adv", Adv.dao.findFirst("select * from adv where categoryid = ? and gender = ?", news.getCategoryid(), genderInt));
            }
            CacheKit.put("news", "newsdetail" + newsId + genderInt + getPageIndex(), object);
        }
        renderJson(new Api(object).get());
    }

    /**
     * 发布评论
     */
    public void writeComment() {
        Long userid = getParaToLong("userid");
        String content = getPara("content");
        Long otherid = getParaToLong("otherid");
        String mtype = getPara("mtype");
        if (StringUtilsWx.isEmpty(content)) {
            return;
        }
        SysUser su = SysUser.dao.findById(userid);
        Comment c = new Comment();
        c.setUserid(userid);
        c.setContent(content);
        c.setOtherid(otherid);
        c.setLogo(su.getLogo());
        c.setName(su.getSname());
        c.setCreattime(DateUtils.getCurDate(DateUtils.COMMON_DATETIME));
        final boolean flag = c.save();
        renderJson(new Api(flag).get());
        updateComments(mtype, otherid);
    }

    /**
     * 更新评论次数
     *
     * @param type
     * @param otherid
     */
    private void updateComments(String type, Long otherid) {
        if ("news".equals(type)) {
            Db.update("update news set commenttimes = commenttimes + 1 where id = ?", otherid);
//            外面的也要更改
            CacheKit.removeAll("news");
        } else if ("image".equals(type)) {
//            只有详细的页面可以通过id来精细控制一点吧。
            CacheKit.removeAll("imageAndVideo");
            CacheKit.removeAll("video");
            CacheKit.removeAll("image");
            Db.update("update image set commenttimes = commenttimes + 1 where id = ?", otherid);
        }
    }

    /**
     * 点赞
     */
    public void doFavForContent() {
        Long cid = getParaToLong("cid");
        //1:news,2:image，3:comment
        Integer xtype = getParaToInt("xtype");
        int flag = 0;
        if (xtype == 1) {
            flag = Db.update("update news set favtimes = favtimes + 1 where id = ?", cid);
            CacheKit.removeAll("news");
        } else if (xtype == 2) {
            flag = Db.update("update image set favtimes = favtimes + 1 where id = ?", cid);
            CacheKit.removeAll("video");
            CacheKit.removeAll("image");
            CacheKit.removeAll("imageAndVideo");
        } else if (xtype == 3) {
//            评论列表是没有缓存的，用的地方少
            flag = Db.update("update comment set fav = fav + 1 where id = ?", cid);
//            CacheKit.removeAll("imageAndVideo");
//            CacheKit.removeAll("news");
//            CacheKit.removeAll("vidoe");
//            CacheKit.removeAll("image");
        }
        renderJson(new Api(flag > 0).get());
    }

    /**
     * 解析腾讯视频数据
     */
    public void parseTencent() {
        String rearUrl = getPara("rearUrl");
        String validUrl = VideoHelper.transUriToValid(rearUrl);
        JSONObject data = new JSONObject();
        data.put("validUrl", validUrl);
        renderJson(new Api(data).get());
    }

    /**
     * 获取图片列表
     */
    public void getImageList() {
        String sql = "from image where 1=1 ";
        String cateogryid = getPara("categoryid");
        String title = getPara("title");
        title = title == null ? "" : title;
        JSONObject object = CacheKit.get("image", "image" + title + cateogryid + getPageIndex());
        if (object != null) {
        } else {
            if (!StringUtilsWx.isEmpty(cateogryid) && !"-1".equals(cateogryid)) {
                sql += "and  categoryid = " + cateogryid;
            }
            if (!StringUtilsWx.isEmpty(title)) {
                sql += " and title like '%" + title + "%'";
            }
            sql += " order by id desc";
            Page<Image> data = Image.dao.paginate(getPageIndex(), PAGE_SIZE, "select * ", sql);
            object = new JSONObject();
            object.put("imageList", data.getList());
            object.put("pageIndex", data.getPageNumber());
            object.put("isLastPage", data.isLastPage());
            CacheKit.put("image", "image" + title + cateogryid + getPageIndex(), object);
        }

        renderJson(new Api(object).get());
    }

    /**
     * 获取图片和视频详情
     */
    public void getImgAndVideoDetail() {
        String imgid = getPara("imgid");
        Image image = Image.dao.findById(imgid);
        if (image == null) {
            renderError(Api.D_204, "未发现改imgid=" + imgid + "的资源");
        }

        Integer genderInt = getParaToInt("gender");

        String xtype = getPara("xtype");
        if (StringUtilsWx.isEmpty(xtype)) {
            image.setReadtimes(image.getReadtimes() + 1);
            image.update();
        }
//        设置interrupttime为0
        Integer interrupttime = image.getInterrupttime();
        if (interrupttime == null) {
            image.setInterrupttime(0);
        }
        String url = image.getUrl();
        if (url == null || url.isEmpty()) {
            if (!StringUtilsWx.isEmpty(image.getRealurl())) {
                VideoHelper.transUrlTovalid(image);
            }
        } else {
            if (url.endsWith("mp4")) {
            } else {
                String updateurltime = image.getUpdateurltime();
                if (updateurltime == null || updateurltime.isEmpty()) {
                    VideoHelper.transUrlTovalid(image);
                } else {
//                    配置文件配置
                    // TODO: 2017/11/21
                    boolean isVideoOutOfTime = DateUtils.isOutOfTime(updateurltime, 4 * 60);
                    if (isVideoOutOfTime) {
                        VideoHelper.transUrlTovalid(image);
                    }
                }
            }
        }
        JSONObject object = CacheKit.get("imageAndVideo", "imageAndVideo" + imgid + genderInt + getPageIndex());
        if (object != null) {

        } else {
            object = new JSONObject();
            object.put("image", image);
            List<Media> mlist = getMedia(image.getId());
            object.put("pics", mlist);
            Page<Comment> data = Comment.dao.paginate(getPageIndex(), PAGE_SIZE, "select * ", "from comment where otherid = ?", imgid);
            object.put("comments", data.getList());
            object.put("pageIndex", data.getPageNumber());
            object.put("isLastPage", data.isLastPage());
            String sql = "select * from image where categoryid = ? and id <> " + imgid + " order by id desc limit 0, 2";
            List<Image> imgList = Image.dao.find(sql, image.getCategoryid());
            JSONArray array = new JSONArray();
            for (Image img : imgList) {
                JSONObject imgjson = new JSONObject();
                imgjson.put("otherImage", img);
                List<Media> lt = getMedia(img.getId());
                if (lt != null && !lt.isEmpty()) {
                    imgjson.put("otherPic", lt.get(0));
                } else {
                    imgjson.put("potherPic", new Media());
                }
                array.add(imgjson);
            }
            object.put("img", array);
            if (genderInt == null) {
                object.put("adv", Adv.dao.findFirst("select * from adv where categoryid = ? ", image.getCategoryid()));
            } else {
                object.put("adv", Adv.dao.findFirst("select * from adv where categoryid = ? and gender = ?", image.getCategoryid(), genderInt));
            }
            CacheKit.put("imageAndVideo", "imageAndVideo" + imgid + genderInt + getPageIndex(), object);

        }
        renderJson(new Api(object).get());
    }

    public static boolean isNumeric(String str) {
        Pattern pattern = Pattern.compile("[0-9]*");
        return pattern.matcher(str).matches();
    }

    /**
     * 获取图片和视频详情videoDetail  videoid
     */
    public void getImgAndVideoDetailForce() {

        String imgid = getPara("imgid");
        Image image = Image.dao.findById(imgid);
        String xtype = getPara("xtype");
        if (StringUtilsWx.isEmpty(xtype)) {
            image.setReadtimes(image.getReadtimes() + 1);
            image.update();
        }
        String url = image.getUrl();
        if (url == null || url.isEmpty()) {
        } else {
            if (url.endsWith("mp4")) {
            } else {
                VideoHelper.transUrlTovalid(image);
            }
        }


        JSONObject object = CacheKit.get("imageAndVideo", "imageAndVideo" + imgid + getPageIndex());
        if (object != null) {

        } else {
            object = new JSONObject();
            object.put("image", image);
            List<Media> mlist = getMedia(image.getId());
            object.put("pics", mlist);
            Page<Comment> data = Comment.dao.paginate(getPageIndex(), PAGE_SIZE, "select * ", "from comment where otherid = ?", imgid);
            object.put("comments", data.getList());
            object.put("pageIndex", data.getPageNumber());
            object.put("isLastPage", data.isLastPage());
            String sql = "select * from image where categoryid = ? and id <> " + imgid + " order by id desc limit 0, 2";
            List<Image> imgList = Image.dao.find(sql, image.getCategoryid());
            JSONArray array = new JSONArray();
            for (Image img : imgList) {
                JSONObject imgjson = new JSONObject();
                imgjson.put("otherImage", img);
                List<Media> lt = getMedia(img.getId());
                if (lt != null && !lt.isEmpty()) {
                    imgjson.put("otherPic", lt.get(0));
                } else {
                    imgjson.put("potherPic", new Media());
                }
                array.add(imgjson);
            }
            object.put("img", array);
            object.put("adv", Adv.dao.findFirst("select * from adv where categoryid = ?", image.getCategoryid()));
            CacheKit.put("imageAndVideo", "imageAndVideo" + imgid + getPageIndex(), object);
        }
        renderJson(new Api(object).get());
    }

    /**
     * 获取视频列表
     */
    public void getVideoList() {
        String sql = "from image where type = 2 ";
        String cateogryid = getPara("categoryid");
        String title = getPara("title");
        JSONObject object = CacheKit.get("video", "video" + title + cateogryid + getPageIndex());
        if (object != null) {
        } else {
            if (!StringUtilsWx.isEmpty(cateogryid) && !"-1".equals(cateogryid)) {
                sql += " and categoryid = " + cateogryid;
            }
            if (!StringUtilsWx.isEmpty(title)) {
                sql += " and title like '%" + title + "%'";
            }
            if ("-1".equals(cateogryid)) {
                sql += " order by readtimes desc";
            } else {
                sql += " order by id desc";
            }
            Page<Image> data = Image.dao.paginate(getPageIndex(), PAGE_SIZE, "select * ", sql);
            object = new JSONObject();
            object.put("imageList", data.getList());
            object.put("pageIndex", data.getPageNumber());
            object.put("isLastPage", data.isLastPage());
            CacheKit.put("video", "video" + title + cateogryid + getPageIndex(), object);
        }
        renderJson(new Api(object).get());
    }


    /**
     * 获取测试列表
     */
    public void getQuestionList() {
        String sql = "from question where 1 = 1 ";
        String cateogryid = getPara("categoryid");
        String title = getPara("title");
        JSONObject object = CacheKit.get("question", "question" + title + cateogryid + getPageIndex());
        if (object != null) {
        } else {
            if (!StringUtilsWx.isEmpty(cateogryid) && !"-1".equals(cateogryid)) {
                sql += " and type = " + cateogryid;
            }
            if (!StringUtilsWx.isEmpty(title)) {
                sql += " and title like '%" + title + "%'";
            }
            String sql1 = sql;
            if ("-1".equals(cateogryid)) {
                sql += " and isbanner = 2 order by testing desc";
            } else {
                sql += " and isbanner = 2 order by id desc";
            }
            Page<Question> data = Question.dao.paginate(getPageIndex(), PAGE_SIZE, "select * ", sql);
            object = new JSONObject();
            object.put("questionList", data.getList());
            object.put("pageIndex", data.getPageNumber());
            object.put("isLastPage", data.isLastPage());
            //获取推荐列表
            sql1 = "select * " + sql1 + " and isbanner = 1 order by id desc limit 0, 2";
            List<Question> list1 = Question.dao.find(sql1);
            object.put("bannerList", list1);
            CacheKit.put("question", "question" + title + cateogryid + getPageIndex(), object);
        }
        renderJson(new Api(Api.S_200, object).get());
    }


    /**
     * 获取测试详情
     */
    public void getQuestionDetail() {
        String questionid = getPara("questionid");
//        int genderInt = getParaToInt("gender");

        Question q = Question.dao.findById(questionid);
        q.setTesting(q.getTesting() + 1);
        q.update();
        JSONObject json = new JSONObject();
        json.put("question", q);
        List<Question> qlist = Question.dao.find("select * from question q where q.type = ? order by q.id desc limit 0, 5", q.getType());
        json.put("others", qlist);
//        json.put("adv", Adv.dao.findFirst("select * from adv where categoryid = ? and gender = ?", q.getType(),genderInt));

        renderJson(new Api(json).get());
    }

    /**
     * 获取列表
     */
    public void getOptions() {
        String questionid = getPara("questionid");
        Question q = Question.dao.findById(questionid);
        List<Options> list = Options.dao.find("select * from options where questionid = ? order by sort desc", questionid);
        JSONObject json = new JSONObject();
        json.put("question", q);
        json.put("optionList", list);
        renderJson(new Api(json).get());
    }

    /**
     * 获取小程序列表
     */
    public void getSmallAppList() {
//        54宝贝55发现
        String cateogryid = getPara("categoryid");
        JSONObject json = CacheKit.get("smallapp", "smallapp" + cateogryid);
        if (json != null) {
        } else {
            json = new JSONObject();
            List<Smallapp> list = Smallapp.dao.find("select * from smallapp where categoryid = ? order by id desc", cateogryid);
            json.put("smallAppList", list);
            CacheKit.put("smallapp", "smallapp" + cateogryid, json);
        }
        renderJson(new Api(json).get());
    }

    /**
     * 验证密码是否正确
     */
    public void checkPasswd() {
        String passwd = getPara("passwd");
        int id = getParaToInt("id");
        int type = getParaToInt("xtype");//1：新闻，2：图片视频
        int uesrid = getParaToInt("userid");
        boolean flag = false;
        if (type == 1) {
            News n = News.dao.findById(id);
            if (n != null) {
                saveContent(passwd, id, type, uesrid);
                flag = passwd.equals(n.getPasswd());
            }
        } else if (type == 2) {
            Image img = Image.dao.findById(id);
            if (img != null) {
                saveContent(passwd, id, type, uesrid);
                flag = passwd.equals(img.getPasswd());
            }
        }
        renderJson(new Api(flag).get());
    }

    private void saveContent(String passwd, int id, int type, int uesrid) {
        if (!StringUtilsWx.isEmpty(passwd)) {
            UserContentPwd ucp = new UserContentPwd();
            ucp.setUserid(uesrid);
            ucp.setOtherid(id);
            ucp.setPasswd(passwd);
            ucp.setType(type);
            ucp.save();
        }
    }

    /**
     * 获取评论列表
     */
    public void getCommentList() {
        Long otherid = getParaToLong("otherid");
        List<Comment> list = Comment.dao.find("select * from comment where otherid = ?", otherid);
        renderJson(new Api(list).get());
    }

    public void getPasswdRoute() {
        String sql = "select * from adv where type = 2";
        Adv adv = Adv.dao.findFirst(sql);
        renderJson(new Api(adv).get());
    }

    /**
     * 提交测试结果
     */
    public void submitResult() {
        Integer score = getParaToInt("score");
        Long questionid = getParaToLong("questionid");
        Long userid = getParaToLong("userid");
        Question q = Question.dao.findById(questionid);
        Results rlt = new Results();
        rlt.setScore(score);
        rlt.setQuestionid(questionid);
        rlt.setUserid(userid);
        rlt.save();
        JSONObject json = new JSONObject();
        json.put("others", rlt.getId());
//        json.put("adv", Adv.dao.findFirst("select * from adv where categoryid = ?", q.getType()));
        renderJson(new Api(json).get());
    }

    /**
     * 生成测试结果
     */
    public void createResults() {
        Long questionid = getParaToLong("questionid");
        Integer score = getParaToInt("score");
        Long userid = getParaToLong("userid");
        Long resultid = getParaToLong("resultid");
        Integer genderInt = getParaToInt("gender");

        Question q = Question.dao.findById(questionid);
        JSONObject json = new JSONObject();
        json.put("question", q);
        List<Question> qlist = Question.dao.find("select * from question q where q.type = ? order by q.id desc limit 0, 5", q.getType());
        json.put("others", qlist);
        //s_score <= score <= e_score
        Score s = Score.dao.findFirst("select * from score where questionid = ? and s_score <= ? and e_score >= ?", questionid, score, score);
        json.put("score", s);
        if (genderInt == null) {
            json.put("adv", Adv.dao.findFirst("select * from adv where categoryid = ? ", q.getType()));
        } else {
            json.put("adv", Adv.dao.findFirst("select * from adv where categoryid = ? and gender = ?", q.getType(), genderInt));
        }
        renderJson(new Api(json).get());
    }

    /**
     * 记录访问vip的记录，下次访问不再需要输入密码
     */
    public void cacheContentPwd() {
        int userid = getParaToInt("userid");
        int otherid = getParaToInt("otherid");
        String pwd = getPara("pwd");
        //1、资讯；2、图片；3、测试
        int type = getParaToInt("xtype");
        String passwd = "";
        if (type == 1) {
            News n = News.dao.findById(otherid);
            if (n != null) {
                passwd = n.getPasswd();
            }
        } else if (type == 2) {
            Image img = Image.dao.findById(otherid);
            if (img != null) {
                passwd = img.getPasswd();
            }
        }
        String sql = "select * from user_content_pwd where userid = ? and otherid = ? and type = ? and passwd = ?";
        UserContentPwd ucp1 = UserContentPwd.dao.findFirst(sql, userid, otherid, type, passwd);
        if (ucp1 == null) {
            renderJson(new Api(true).get());
        } else {
            renderJson(new Api(false).get());
        }
    }


    private List<Media> getMedia(long otherid) {
        //Map<Long, List<Media>> map = new HashMap<>();
        return Media.dao.find("select * from media where otherid = ?", otherid);
        /*List<Media> list = new ArrayList<>();
        for (Media m : data) {
            if (!map.containsKey(m.getOtherid())){
                map.put(m.getOtherid(), list);
                list = new ArrayList<>();
            }
            list.add(m);
        }
        return map;*/
    }

    /**
     * 没用自己测试
     */
    public void checkSignature() {
        String signature = getPara("signature");
        String timestamp = getPara("timestamp");
        String nonce = getPara("nonce");
        String echostr = getPara("echostr");

        String token = Constants.XCX_TOKEN;
        ArrayList<String> list = new ArrayList<String>();
        list.add(nonce);
        list.add(timestamp);
        list.add(token);
        Collections.sort(list);
        String tempStr = DigestUtils.shaHex(list.get(0) + list.get(1) + list.get(2));
//微信返回的加密串
        if (tempStr.equals(signature)) {
            renderText(echostr);
        } else {
            renderText("false");
        }
    }

    public void saveOpenid() {
        String openid = getPara("openid");
        String formid = getPara("formid");
        Xcxmessage xcxmessage = new Xcxmessage();
        xcxmessage.setFormid(formid);
        xcxmessage.setOpenid(openid);
        xcxmessage.setCreatetime(System.currentTimeMillis());
        xcxmessage.setIsvalid(1);
        xcxmessage.save();
    }

    public void sendTemplate(VideoInfoModel videoInfoModel) {
        long cutTime = System.currentTimeMillis() - 7 * 24 * 60 * 1000 * 60L;
        List<Xcxmessage> xcxmessageList = Xcxmessage.dao.find("select * from xcxmessage where createtime > " + cutTime + " group by openid");
        String accessTokeJson = WxHelper.requestAccessToke();
        if (!StringUtilsWx.isEmpty(accessTokeJson)) {
            String access_token = JSON.parseObject(accessTokeJson).getString("access_token");
            String url = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=" + access_token;
            for (Xcxmessage xcxmessage :
                    xcxmessageList) {
                WxHelper.sentTemplateMessage(url, xcxmessage, videoInfoModel, "");
//                xcxmessage.dao().deleteById(xcxmessage.getId());
                Db.update("delete from xcxmessage where id = " + xcxmessage.getId());
            }
        }
    }

    public void getSystemDict() {
        String name = getPara("name");
        List<SysDict> list = SysDict.dao.find("select * from sys_dict where name = ?", name);
        if (list != null && list.size() == 1) {
            SysDict sysDict = list.get(0);
            renderText(sysDict.getDValue());
        } else {
            renderText("not find");
        }
    }

    public void getAccessToken() {
        String accessToken = WxHelper.requestAccessToke();
//        HttpServletRequest request = getRequest();
        if (StringUtilsWx.isEmpty(accessToken)) {
            renderJson(new Api(D_204, accessToken).get());
        } else {
            renderJson(new Api(accessToken).get());
        }
    }

    public void getQrCodeByB() {
        HttpServletRequest request = getRequest();
        String filePath = WxHelper.getQrCodeB(request);
//        getFileUploadPath()
//        {"errcode":41030,"errmsg":"invalid page hint: [lParHa03491513]"}
        if (!StringUtilsWx.isEmpty(filePath)) {
//            getResponse().setContentType("image/png");
            if (filePath.contains("errcode")) {
                renderJson(new Api(D_204, filePath).get());
            } else {
                renderJson(new Api(filePath).get());
            }
        } else {
            renderJson(new Api(D_204, filePath).get());
        }
    }


    public void clearCache() {
        CacheKit.removeAll("news");
        CacheKit.removeAll("image");
        CacheKit.removeAll("imageAndVideo");
        CacheKit.removeAll("smallapp");
        CacheKit.removeAll("cache");
        CacheKit.removeAll("category");
        CacheUtils.removeAllByCacheName("frequentlyquestion");
        CacheKit.removeAll("festivaltype");
        CacheKit.removeAll("blessword");
        CacheKit.removeAll("video");
        CacheKit.removeAll(CacheUtils.CACHEUTILS);
        renderText("success");
    }

    public void clearCacheAll() {
        List<Dbtable> dbtables = Dbtable.dao.find("select * from dbtable ");
//            password=bsmysqladmin
//            jdbcUrl1=jdbc:mysql://116.255.202.75/
        for (Dbtable dbtable : dbtables
                ) {
            String tempJdbcUrl = dbtable.getJdbcurl();
            String tempProjectname = dbtable.getTablename();
//                jdbc:mysql://127.0.0.1:3306/
            String url_clear = tempJdbcUrl.replace("jdbc:mysql://", "") + tempProjectname + "/api/clearCache";
            WxHelper.requestUrl(url_clear);
        }
        renderText("success");
    }

    public void prePay() {
//        下限0.1元，上限100元，超过的话，提示（前台提示就可以了）
//        钱传过来的单位为分，
//        wx_code：微信code
//        amounts：金额
//        hb_number：红包个数
//        getParaToInt();
//        防止用户多次点击的处理
        String money_amounts = getPara("amounts");
        String cost_fee = getPara("cost_fee");
        String hb_number = getPara("hb_number");
        int moneyNum = 0;//付款总数量
        int hb_num = 0;
        int cost_fee_int = 0;
//        int money_amounts_int = 0;

        try {
            cost_fee_int = Integer.parseInt(cost_fee);
        } catch (NumberFormatException e) {
            cost_fee_int = -1;
            e.printStackTrace();
        }
        try {
            moneyNum = Integer.parseInt(money_amounts) + cost_fee_int;
        } catch (NumberFormatException e) {
            moneyNum = -1;
            e.printStackTrace();
        }
        try {
            hb_num = Integer.parseInt(hb_number);
        } catch (NumberFormatException e) {
            hb_num = -1;
            e.printStackTrace();
        }
        if (moneyNum == -1 || hb_num == -1 || cost_fee_int == -1) {
            renderJson(new Api(Api.A_202, "参数错误").get());
            return;
        }
//        moneyNum = money_amounts_int - cost_fee_int;
        if (moneyNum < 1 || (moneyNum - cost_fee_int) < hb_num) {
            renderJson(new Api(Api.A_202, "钱太少了多冲一点吧").get());
            return;
        }
        Date date = new Date();
        String timeStart = TimeUtils.getFormatTime(date, Constant.TIME_FORMAT);
        String openid = getPara("openid");

//        openid = "ov91F43PNpjX15NDeHGw_QB8g0do";
        if (!StringUtilsWx.inPool(openid)) {
//                orderid.intern()可以获得常量池里的
            openid = openid.intern();
        }
        synchronized (openid) {
            String randomOrderId = CommonUtil.getRandomOrderId();
            Order orderNew = new Order();
            orderNew.setCostFee(cost_fee_int);
            orderNew.setOrderid(randomOrderId);
            orderNew.setOrdercount(hb_num);
            orderNew.setOrderfee(moneyNum);
            orderNew.setOrdertime(timeStart);
            orderNew.setState(2);
            orderNew.setUserid(openid);
//        通过
            SysUser sysUser = SysUser.dao.findFirst("select * from sys_user where userid ='" + openid + "'");
            if (sysUser != null) {
                orderNew.setUser(sysUser.getSname());
            } else {
                orderNew.setUser("用户表无该用户");
                orderNew.setState(4);
                orderNew.save();
            }
//      根据userid查到账户余额userBalance，如果userBalance-money大于0，返回结果就不需要支付，＜0，差值就是这次要支付的
//        每次进来都首先建立一个Order表，所有的都按照商户id来做，成功或失败的，从账户里扣的还是别的什么的，
            if (sysUser != null) {
                int userBalance = 0;
                if (sysUser.getBalance() != null) {
                    userBalance = sysUser.getBalance();
                }
                int dif = userBalance - moneyNum;
                if (dif >= 0) {
//                更改一下数据库就好
                    sysUser.setBalance(dif);
                    OrderUtils.recordUserCash(-moneyNum, randomOrderId, openid, dif, "全部用账户余额支付", Constant.USER_CASHTYPE_EXPEND);
                    sysUser.update();
                    DbCacheFindUtls.removeSysUser(openid);

//                直接分，数据存储到SplitHb中
//                自己生成一个订单号返回就好了
//                也需要插入一个Order吧，
//                分红包到Split_hb数据库之中
                    PayUtils.splitMoney(moneyNum, hb_num, openid, randomOrderId, cost_fee_int);
                    orderNew.setAcountdeduct(moneyNum);
                    orderNew.setWxrecharge(0);
                    orderNew.setState(1);
                    orderNew.save();
                    JSONObject json = new JSONObject();
                    json.put("orderid", randomOrderId);
                    renderJson(new Api(json, "账户余额支付完成").get());
                } else {
                    orderNew.setAcountdeduct(userBalance);
                    orderNew.setWxrecharge(-dif);
                    boolean isOrderSavaSuccess = orderNew.save();
                    if (!isOrderSavaSuccess) {
                        renderJson(new Api(Api.D_204, "Order保存失败请重试").get());
                        return;
                    }
//                SysUser里面是不扣的，等到收到腾讯的支付成功通知后再去减吧
                    String prePayResult = PayControllerUtil.prePay(openid, getRequest(), -dif, hb_num, randomOrderId);
                    if (!StringUtilsWx.isEmpty(prePayResult)) {
                        // TODO: 2018/2/3 同一替换成标准json方法
                        JSONObject json = new JSONObject();
                        json.put("prePayResult", prePayResult);
                        renderJson(new Api(json).get());
                    } else {
//              不会发生
                        renderJson(new Api(Api.D_204, "请求失败").get());
                    }
                }
            } else {
                renderJson(new Api(Api.D_204, "sysUser为空").get());
//            传的openid有误或该openid没有存入用户表中,或数据库中存在重复的
            }
        }
    }

    public void payNotify() throws Exception {
//        微信支付结果通知，这里不会返回system_error的，要不然就没有返回
        BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) getRequest().getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        //sb为微信返回的xml
        String notityXml = sb.toString();
        String resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                + "<return_msg><![CDATA[returnCode is not success]]></return_msg>" + "</xml> ";
        log.error("接收到的报文：" + DateUtils.getCurDateStr() + notityXml);
//        System.out.println("接收到的报文："+DateUtils.getCurDateStr() + notityXml);
        Map map = PayUtils.doXMLParse(notityXml);
//        ![CDATA[支付测试],这个是直接会过滤的
        String returnCode = (String) map.get("return_code");
        //                再调用接口，如果数据库出现错误的话，
//                在事务里操作数据库，如果失败的话，抛出异常，在catch里面回滚，之后向微信后台传回FAIL
//        transaction_id  微信订单号，需要在Order里面用的是否也要写入订单表里面
        if ("SUCCESS".equals(returnCode)) {
            //验证签名是否正确
            String result_code = (String) map.get("result_code");
            String out_trade_no = (String) map.get("out_trade_no");
            String openid = (String) map.get("openid");
            String cash_fee = (String) map.get("cash_fee");
            String total_fee = (String) map.get("total_fee");
//            total_fee等于cash_fee和代金卷的和
            String transaction_id = (String) map.get("transaction_id");
            //再次签名，这个签名用于小程序端调用wx.requesetPayment方法
//            prepay sign sign ,verify sign等都是不同的
            if (PayUtils.verify(PayUtils.createLinkString(map), (String) map.get("sign"), Constant.APP_KEY, "utf-8")) {
//            if (true) {
                /**此处添加自己的业务逻辑代码start**/
                boolean isTransationSuccess = Db.tx(new IAtom() {
                    @Override
                    public boolean run() throws SQLException {
//                [CDATA[870595779]]
//                从订单表里面查，
                        Order order = Order.dao.findFirst("select * from  `order` where orderid ='" + out_trade_no + "'");
                        if ("SUCCESS".equals(result_code)) {
                            if (order != null) {
                                int state = order.getState();
                                if (state == 1) {
//                        表示充值已经成功了
                                    log.error("state为1，已经成功过了");
                                } else {
                                    int total_fee_int = -1;
                                    try {
                                        total_fee_int = Integer.parseInt(total_fee);
                                    } catch (NumberFormatException e) {
                                        e.printStackTrace();
                                    }
//                            transaction_id是现在才得到的，
                                    order.setWxTransactionId(transaction_id);
                                    String orderid = order.getOrderid();
                                    int ordercount = order.getOrdercount();
                                    int orderfee = order.getOrderfee();
                                    int costFee = order.getCostFee();
                                    int acountDeduct = order.getAcountdeduct();
                                    if (total_fee_int == (orderfee - acountDeduct)) {
                                        order.setState(Constant.ORDER_STATE_SUCCESS);
//                        将钱分到几个账户中吧,分万千user表中这个人就没有钱了，这个钱是不会加到这个人的user里面的，
                                        PayUtils.splitMoney(orderfee, ordercount, openid, orderid, costFee);
//更改用户余额,不需要更改用户余额呀，成后直接就
                                        String openidCoyp = "";
                                        if (!StringUtilsWx.inPool(openid)) {
                                            openidCoyp = openid.intern();
                                        } else {
                                            openidCoyp = openid.intern();
                                        }
                                        synchronized (openidCoyp) {
                                            List<SysUser> sysUsers = SysUser.dao.find("select * from sys_user where userid = ?", openid);
                                            if (sysUsers != null && sysUsers.size() == 1) {
                                                SysUser sysUser = sysUsers.get(0);
                                                int balance = sysUser.getBalance() == null ? 0 : sysUser.getBalance();
                                                sysUser.setBalance(balance - acountDeduct);
                                                boolean isUpdateSuccess = sysUser.update();
                                                if (!isUpdateSuccess) {
                                                    return false;
                                                }
                                                OrderUtils.recordUserCash(-acountDeduct, orderid, openid, balance - acountDeduct, "微信支付成功收到微信后台通知", Constant.USER_CASHTYPE_EXPEND);
                                            } else {
                                                return false;
                                            }
                                        }
                                        boolean isUpdateSuccess = order.update();
                                        if (!isUpdateSuccess) {
                                            return false;
                                        }
                                    } else {
                                        log.error("数额不符合，或者coupon_fee不为int的String");
                                        return false;
//                            数额不符合，或者coupon_fee不为int的String
                                    }
                                }
                            } else {
                                log.error("order 为null");
                                return false;
                            }
//        收到微信端的确认信息，
//        如果成功的话，就要将红包分为n份，记录到数据库之中，
//        应该有一个表记录这些订单的参数，
                            /**此处添加自己的业务逻辑代码end**/
                            //通知微信服务器已经支付成功
                        } else {
                            log.error("result_code结果为FALSE");
                            if (order != null) {
                                order.setState(3);
                                boolean isSuccess = order.update();
                                if (!isSuccess) {
                                    return false;
                                }
                            }
                        }
                        return true;
                    }
                });
                if (isTransationSuccess) {
//                    事务成了
                    resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                            + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                }
            } else {
//                签名不正确不处理就行了，也要返回成功
                resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                        + "<return_msg><![CDATA[verify not success]]></return_msg>" + "</xml> ";
            }
        } else {
//            Order内写入交易失败吧
        }
        log.error("微信支付回调结果：" + resXml);
//        按照微信的要求返回resXml
        renderText(resXml);
    }


    //提现时出现错误必须回滚
//提现
    public void withdrawCash() {
//        是不是和节日类型有关
        String openid = getPara("openid");
        String cash_amounts = getPara("cash_amounts");
        // TODO: 2018/2/6 是不是要一个最大的限额呢。
//        咋么防止重复点击呢
        int moneyNum = -1;
        try {
            moneyNum = Integer.parseInt(cash_amounts);
        } catch (NumberFormatException e) {
            moneyNum = -1;
            e.printStackTrace();
        }
//        renderJson只有带return时或结束时，才会rederJson成功
        if (moneyNum < 0) {
            renderJson(new Api(Api.A_202, "cash_amounts参数错误").get());
            return;
        }
//        做好代码搞好同步吧
        JSONObject jsonObject = RedPacketSplitUtil.withdrawCash(PayUtil.getLocalIp(getRequest()), openid, moneyNum, false);
//        那就要在这里做同步了吧，用openid做同步，防止重复点击多次提现吧。如果余额不够就去
        renderJson(jsonObject);
    }


    /**
     * 获取orderid对应的分红包
     */
    public void getSplitHbs() {
//        需不需要做验证呢
        // TODO: 2018/2/9 可以做缓存的 ，只有领取红包时才会改变数据库吧
        String userid = getPara("userid");
        String orderid = getPara("orderid");
//        JSONObject json = CacheKit.get("smallapp", "smallapp" + cateogryid);
        JSONObject json = new JSONObject();
        if (!StringUtil.isEmpty(userid) && !StringUtil.isEmpty(orderid)) {
            String mysqlReceiver = "SELECT * FROM split_hb where orderid = ? and receiverid =?";
            String mysql = "SELECT * FROM split_hb where orderid = ?";
            List<SplitHb> splitHbs = SplitHb.dao.find(mysql, orderid);
//缓存因该精细一点吧，封装一个公交，SplitHb的工具，
            List<SplitHb> splitHbsReceiver = SplitHb.dao.find(mysqlReceiver, orderid, userid);
            json.put("splitHbs", splitHbs);
            if (splitHbsReceiver != null) {
                if ((splitHbsReceiver.size() > 0)) {
                    json.put("hasGetSplit", "YES");
                } else {
                    json.put("hasGetSplit", "NO");
                }
            } else {
                renderJson(new Api(Api.L_203, "查询出错").get());
            }
//            CacheKit.put("smallapp", "smallapp" + cateogryid, json);
            renderJson(new Api(json).get());
        } else {
            renderJson(new Api(Api.A_202, "获取不到商家订单id").get());
        }
    }

    //领取红包的操作
    public void acceptOneHb() {
        String time = DateUtils.getCurDateStr();
        String orderid = getPara("orderid");
        String openid = getPara("openid");
//        该订单号下的，这个单号不应该传的
        if (StringUtilsWx.isEmpty(orderid) || StringUtilsWx.isEmpty(openid)) {
            renderJson(new Api(Api.A_202, "获取参数错误").get());
        } else {
            if (!StringUtilsWx.inPool(orderid)) {
//                orderid.intern()可以获得常量池里的
                String s2 = orderid.intern();
//                会发生不是同一个orderid的内容的
                log.error("常量池hashcode：" + s2.hashCode());
                orderid = s2;
                log.error("orderid hashcode：" + orderid.hashCode());
            }
            //用orderid锁住，是不是别的orderid的就可以进去，但是相同的orderid的就进不去了
//            这样子行不行就不一定了,因为每一次的orderid其实是不同的
//            修改同一个数据库的，最好改为同一个抽出来的方法
            synchronized (orderid) {

                log.error("进入m_order：" + "orderid" + orderid);
//                这个也只会调用一次的
                String queryMysql = "SELECT * FROM split_hb where orderid = ? and receiverid = ? ";
                SplitHb splitHbQuery = SplitHb.dao.findFirst(queryMysql, orderid, openid);
                if (splitHbQuery != null) {
                    renderJson(new Api(Api.R_205, "已领取过该红包了").get());
                    return;
                }
                String mysql = "SELECT * FROM split_hb where orderid = ? and state = ? ";
//                 虽然m_order是int类型的，但是 这里可以直接接受String类型的，
                SplitHb splitHb = SplitHb.dao.findFirst(mysql, orderid, Constant.SPLIT_HB_STATE_NEW);
                if (splitHb != null) {
                    if (openid.equals(splitHb.getUserid())) {
                        renderJson(new Api(Api.R_205, "不能领取自己的红包").get());
                        return;
                    }
                    if (splitHb.getState() == Constant.SPLIT_HB_STATE_NEW) {
                        SysUser sysUser = SysUserUtil.getSysUser(openid);
                        String urlLogo = "";
                        String tittle = "";
                        if (sysUser != null) {
                            urlLogo = sysUser.getLogo();
                            tittle = sysUser.getSname();
                        }
                        splitHb.setReceiverLogourl(urlLogo);
                        splitHb.setReceiverTittle(tittle);
                        splitHb.setReceivertime(time);
                        splitHb.setState(Constant.SPLIT_HB_STATE_OPENED);
                        splitHb.setReceiverid(openid);
                        splitHb.update();
//                        HkopenRecord
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("splitHb", splitHb);
                        int split_fee = splitHb.getHbfee();
//                      领取后个人账户金钱还要增加的   （拆红包时，服务器要告诉客户端有没有领到红包，领到多少钱）
//                      领取红包后要将贺卡写入，通过orderid，得到issend=1的红包，只有一个，
//                      RedPacketSplitUtil.saveGreetingCard(orderid, openid, split_fee);
                        RedPacketSplitUtil.addCashToUser(orderid, openid, split_fee, "领取红包", Constant.USER_CASHTYPE_INCOME);
                        DbCacheFindUtls.removeHkTablesGet(openid);//清楚缓存
                        DbCacheFindUtls.removeSplitHbByReceiver(openid);//清楚缓存
                        renderJson(new Api(jsonObject).get());
                    } else if ((splitHb.getState() != 1)) {
                        renderJson(new Api(Api.R_205, "状态值不为1，已被领取或过期").get());
                    } else {
                        log.error("acceptOneHb splitHb ==null or state is not 1 orderid openid:" + orderid + ":" + openid);
                        renderJson(new Api(Api.A_202, "参数错误").get());
                    }
                } else {
//                    记录领取的无现金的红包，收到的贺卡，只要点开就行了，和有没有红包没多大关系的
                    renderJson(new Api(Api.D_204, "红包已被领完了").get());
                }
            }
        }
    }

    /**
     * 生成贺卡，
     * 也没有多大的空间
     */
    public void createGreetingCard() {
//        如果要获取领到的贺卡，则去split表里面查receiver的userid
//        是不是可以传来transitionid吗或者只要客户端确认支付了，治理也就确认是支付的
//        通过openid和orderid来共同确定
        String orderid = getPara("orderid");
        String openid = getPara("openid");
        String urltype = getPara("urltype");
        String url = getPara("url");
        String word = getPara("word");
        String issend = getPara("issend");
        String cash_amounts = getPara("cash_amounts");
//        这个方法如果没有返回参数直接挂的
        String festival_type = getPara("festival_type");
        String hashb = getPara("hashb");
        String m_order = getPara("m_order");
        String logo_url = getPara("logo_url");
        String title = getPara("title");
//        先查询这个orderid的贺卡有没有，如果没有再添加吧。
        if (!StringUtil.isEmpty(orderid)) {
            if (HkTable.dao.findFirst("select * from hk_table where orderid = ? and userid= ?", orderid, openid) != null) {
                renderJson(new Api(Api.L_210, "该orderid的贺卡已经生成了").get());
                return;
            }
        }
        // TODO: 2018/2/2
//        这里的cash_amounts是支付后的，应该再去查一下订单，这个订单是否支付完成，如果没有完成主动去微信后台查询
        HkTable hkTable = new HkTable();
        hkTable.setOrderid(orderid);
        hkTable.setLogoUrl(logo_url);
        hkTable.setTitle(title);
        hkTable.setWord(word);
        hkTable.setUrl(url);
        hkTable.setUserid(openid);
        int urltype_int = -1;
        int issend_int = -1;
        int cash_amounts_int = -1;
        int hashb_int = -1;
        int festival_type_int = -1;
        try {
            urltype_int = Integer.parseInt(urltype);
            issend_int = Integer.parseInt(issend);
            hashb_int = Integer.parseInt(hashb);
            festival_type_int = Integer.parseInt(festival_type);
        } catch (NumberFormatException e) {
            e.printStackTrace();
            renderJson(new Api(Api.A_202, "String转Int失败").get());
            return;
        }
        hkTable.setFestivalType(festival_type_int);
        hkTable.setUrltype(urltype_int);
        hkTable.setHashb(hashb_int);
        hkTable.setIssend(issend_int);
        if (hashb_int == Constant.GREETCARD_HAS_HB) {
            try {
                cash_amounts_int = Integer.parseInt(cash_amounts);
            } catch (NumberFormatException e) {
                e.printStackTrace();
                renderJson(new Api(Api.A_202, "String转Int失败").get());
                return;
            }
            String isSuccess = GreetingCardUtils.isOderCashSuccess(hashb, issend, cash_amounts, orderid);
            if (!"SUCCESS".equals(isSuccess)) {
                renderJson(new Api(Api.A_202, isSuccess).get());
                return;
            }
            hkTable.setBanance(cash_amounts_int);
        } else {
//            无红包并且orderid为空自己生成
            if (StringUtil.isEmpty(orderid)) {
                orderid = CommonUtil.getRandomOrderId();
            }
        }
        boolean isSuccess = hkTable.save();
        if (isSuccess) {
            DbCacheFindUtls.removeHkTablesGet(openid);//清楚缓存
            DbCacheFindUtls.removeHkTables(openid);
            JSONObject jsonObject = new JSONObject();
            renderJson(new Api(jsonObject).get());
        } else {
            renderJson(new Api(Api.E_201, "数据库保存失败，请重试").get());
        }
    }

    /**
     * 获取贺卡
     */
    public void getgreetingCardsByisSend() {
//        其实openid等等都应该Constant话,
//        判断有无钱包，
        // TODO: 2018/2/9 这里只有自己点击的时候才会用到的吧，每个手机上用到的都是单独的
        String openid = getPara("openid");
        String issend = getPara("issend");
//        int issend_int = -1;
        // TODO: 2018/2/2
        if (StringUtil.isEmpty(openid) || StringUtil.isEmpty(issend)) {
            renderJson(new Api(Api.E_201, "参数错误").get());
        }
        int issend_int = 0;
        try {
            issend_int = Integer.parseInt(issend);
        } catch (NumberFormatException e) {
            e.printStackTrace();
//            像这种可以做一个列表，给用户看的，给开发人员看的，版本不同内容同的
            renderJson(new Api(Api.A_202, "String转int出错").get());
            return;
        }
        JSONObject jsonObject = new JSONObject();
        if (issend_int == Constant.SPLIT_HB_SEND) {

            jsonObject = RedPacketSplitUtil.getSplitSend(openid, jsonObject, issend_int);
        } else if (issend_int == Constant.SPLIT_HB_GET) {
            jsonObject = RedPacketSplitUtil.getSplitGet(openid, jsonObject);
        } else {
        }
        renderJson(new Api(jsonObject).get());
    }

    /**
     * 在小程序的回调里面
     */
    public void updateSendHktable() {
//        无红包时，orderid时间戳，和openid可以确定一条order吧，确认贺卡时必须传open第
        String orderid = getPara("orderid");
        String openid = getPara("openid");
        HkTable hkTable = HkTable.dao.findFirst("select * from hk_table where orderid = ? and userid = ?", orderid, openid);
        if (hkTable != null) {
            hkTable.setIssend(Constant.SPLIT_HB_SEND);
            hkTable.update();
            renderJson(new Api().get());
        } else {
            renderJson(new Api(Api.D_204, "没有此orderid的贺卡").get());
        }
    }

//    public void copyHkTableForNewUser() {
//        String orderid = getPara("orderid");
//        String openid = getPara("openid");
//        String hkOpenid = getPara("hkOpenid");//转发的人的userid
//        String logo_url = getPara("logo_url");
//        String title = getPara("title");
//        HkTable hkTable = HkTable.dao.findFirst("select * from hk_table where orderid =? and openid =?", orderid, openid);
//        if (hkTable != null) {
//            String randomOrderId = CommonUtil.getRandomOrderId();
//            HkTable hkTable1=   newHkTable(hkTable,logo_url,title,randomOrderId,hkOpenid);
//            if (hkTable.save()) {
//                renderJson(new Api().get());
//            } else {
//                renderJson(new Api(Api.D_207, "数据库保存失败").get());
//            }
//        } else {
//            renderJson(new Api(Api.D_204, "没有此orderid的贺卡").get());
//        }
//    }

    private HkTable newHkTable(HkTable hkTable, String logoUrl, String title, String randomOrderId, String openid) {
        HkTable hkTable1 = new HkTable();
        hkTable1.setIssend(hkTable.getIssend());
        hkTable1.setFestivalType(hkTable.getFestivalType());
        hkTable1.setHashb(hkTable.getHashb());
        hkTable1.setUserid(openid);
        hkTable1.setBanance(hkTable.getBanance());
        hkTable1.setTitle(title);
        hkTable1.setLogoUrl(logoUrl);
        hkTable1.setWord(hkTable.getWord());
        hkTable1.setUrl(hkTable.getUrl());
        hkTable1.setUrltype(hkTable.getUrltype());
        hkTable1.setSplitOrder(hkTable.getSplitOrder());
        hkTable1.setOrderid(randomOrderId);
        return hkTable1;
    }

//如果自己点自己的，那肯定不能点

    /**
     * 获取单个的贺卡信息
     * 做缓存没有意义,因为单个贺卡的话，只有几个人会用同一份数据的
     */
    public void getGreetingCard() {
//        openid和orderid共同确定一个贺卡吧
//        其实openid等等都应该Constant话,如果只有一个的话，应该
        String orderid = getPara("orderid");
//        贺卡自带的userid
        String userid = getPara("userid");
        String originuser = getPara("originuser");
        if (StringUtil.isEmpty(orderid) || StringUtil.isEmpty(userid)) {
            renderJson(new Api(Api.D_204, "数据为空").get());
        } else {
            StringBuffer sqlBuffer = new StringBuffer("select * from hk_table where orderid ='" + orderid + "' and userid='" + originuser + "'");
            HkTable hkTable = HkTable.dao.findFirst(sqlBuffer.toString());
//            HkTable hkTable = DbCacheFindUtls.getHkTable(orderid, originuser);
            if (hkTable != null) {
//                userid和originuserid要不同的
                if (!userid.equals(hkTable.getUserid())) {
                    GreetingCardUtils.recordOpenHk(orderid, userid, originuser);
                }
                DbCacheFindUtls.removeHkTablesGet(userid);//清楚缓存
//                DbCacheFindUtls.removeSplitHbByReceiver(userid);//清楚缓存
//                这里加userid判断有什么用呢，一定要思路清晰，（不存在什么保险点的问题，1就是1，2就是2）
                String mysql = "SELECT * FROM split_hb where orderid = '" + orderid+"'";
//                        + "' and userid = '" + originuser + "'";
//                String mysql = "SELECT * FROM split_hb where orderid = '" + orderid + "' and userid = '" + originuser + "'";
                //虽然m_order是int类型的，但是 这里可以直接接受String类型的，
                List<SplitHb> splitHbList = SplitHb.dao.find(mysql);
//                List<SplitHb> splitHbList = DbCacheFindUtls.getSplitHbsByOrderid(orderid);
                int acceptNums = 0;
                for (SplitHb splitHb : splitHbList
                        ) {
                    if (splitHb.getState() == Constant.SPLIT_HB_STATE_OPENED) {
                        acceptNums++;
                    }
                }
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("acceptNums", acceptNums);
                jsonObject.put("hkTable", hkTable);
                jsonObject.put("splitHbList", splitHbList);
                renderJson(new Api(jsonObject).get());
            } else {
                renderJson(new Api(Api.D_204, "查询无此贺卡").get());
            }
        }
    }

    /**
     * 获取祝福语,缓存已做了。
     */
    public void getBlessWord() {
        String sql = "from bless_word where 1 = 1 ";
        String festivaltype = getPara("festivaltype");
        String categoryid = getPara("categoryid");
//        String word = getPara("word");
        JSONObject object = CacheKit.get("blessword", "blessword" + festivaltype + categoryid + getPageIndex());
        if (object != null) {
        } else {
            if (!StringUtilsWx.isEmpty(festivaltype) && !"-1".equals(festivaltype)) {
                sql += " and festivaltype = " + festivaltype;
            }
            if (!StringUtilsWx.isEmpty(categoryid) && "-1".equals(categoryid)) {
                sql += " order by choicecount desc";
            } else {
                sql += " order by id desc";
            }
            Page<BlessWord> data = BlessWord.dao.paginate(getPageIndex(), 100, "select * ", sql);
            object = new JSONObject();
            object.put("blessWordList", data.getList());
            object.put("pageIndex", data.getPageNumber());
            object.put("isLastPage", data.isLastPage());
            CacheKit.put("blessword", "blessword" + festivaltype + categoryid + getPageIndex(), object);
        }
        renderJson(new Api(object).get());
    }

    /**
     * 获取祝福语,祝福语也是一直从缓存里面拿的吗
     * 后台请求的应该是最新的一个吧
     */
    public void getOneBlessWord() {
        JSONObject object = new JSONObject();
        String festivaltype = getPara("festivaltype");
        String cateogryid = getPara("cateogryid");
        BlessWord data = DbCacheFindUtls.getOneBlessWord(cateogryid, festivaltype);
        object.put("blessword", data == null ? "" : data);
        renderJson(new Api(object).get());
    }

    /**
     * 获取背景音乐
     */
    public void getBgMusicRandom() {
//        是不是和节日类型有关
//        可以设置缓存
        String festivaltype = getPara("festivaltype");
        int randomInt = new Random(20).nextInt();
        MusicBg musicBg = DbCacheFindUtls.getMusicBg(randomInt, festivaltype);
        JSONObject json = new JSONObject();
        if (musicBg == null) {
            renderJson(new Api(Api.D_204, "数据为空").get());
        } else {
            json.put("bgMusic", musicBg);
            renderJson(new Api(json).get());
        }
    }

    /**
     * 获取常见问题
     */
    public void getFrequentlyQuestion() {
        Page<FrequentlyQuestion> data = DbCacheFindUtls.getFrequentlyQuestion(getPageIndex());
        JSONObject object = new JSONObject();
        object.put("blessWordList", data.getList());
        object.put("pageIndex", data.getPageNumber());
        object.put("isLastPage", data.isLastPage());
        renderJson(new Api(object).get());
    }

    /**
     * 获取节日类型
     */
    public void getFestivalTypes() {
        String sql = "select *  from category where parentid = 7 order by id";
        JSONObject object = CacheKit.get("category", "category" + getPageIndex());
        if (object != null) {
        } else {
            List<Category> categoryList = Category.dao.find(sql);
            object = new JSONObject();
            object.put("categoryList", categoryList);
            CacheKit.put("category", "category" + getPageIndex(), object);
        }
        renderJson(new Api(object).get());
    }

    /**
     * 选中一次祝福语
     */
    public void choiceBlessWord() {
        int id = 0;
        try {
            id = getParaToInt("id");
        } catch (Exception e) {
            e.printStackTrace();
            renderJson(new Api(Api.L_203, "id不存在!").get());
            return;
        }
        BlessWord blessWord = BlessWord.dao.findFirst("select * from bless_word where id =?", id);
        if (blessWord != null) {
            blessWord.setChoicecount(blessWord.getChoicecount() + 1);
            blessWord.update();
            CacheKit.removeAll("blessword");
            renderJson(new Api().get());

        } else {
            renderJson(new Api(Api.D_204, "查不到对应的祝福语").get());
        }
    }
//数据读写的地方确定好，加好缓存吧

    //    启用缓存很简单，只需要放入 ehcache.xml 与 jar 包并在 configPlugin中添加一句 : me.add(new EhCachePlugin())就可以使用了。 JFinal 缓存主要有如下几种用法：
//            1：使用 CacheInterceptor对 actoin 进行全自动缓存
//    这种用法非常适用于网站首页，以及网站各大频道，设置好一个合理的过期时间即可。该用法会自动化缓存整个 action 所需的所有数据。
//            2：使用 CacheKit 工具类在程序中辅助做缓存
//    这种用法适合更加细粒度地控制需要缓存的数据，例如，你仅仅需要缓存某 action 中的某个 List 数据，可以使用 CacheKit，具体使用例子见 JFinal 手册。
//            3：使用 JFinal ActiveRecord 中的 Model 与 Db
//    这种用法可以将 ActiveRecord 与缓存结合起来使用，是最省代码的一种使用方式，优点是简单方便、省代码，缺点是查询业务耦合度有所提升。
//    被存缓存的对象何时存入缓存，得看具体情况，三种用法有点区别。
//    JFinal 缓存采用了最简单的策略，仅缓存不负责更新数据，开发者需要根据不同的业务通过 CacheKit 中的方法主动清除缓存数据。
//    对于读多写少的 web 站点，设置好适当的过期时间，在适当的地方清除缓存能非常有效地提升性能。
    public void getUserInfo() {
//        这里可以做缓存的
        // TODO: 2018/2/8 这个可以做缓存的吧·1·但改动的地方比较多吧
        String userid = getPara("openid");
        SysUser sysUser = SysUser.dao.findFirst("select * from sys_user where userid = ?", userid);
        if (sysUser != null) {
            JSONObject object = new JSONObject();
            object.put("sysUser", sysUser);
            renderJson(new Api(object).get());
        } else {
            renderJson(new Api(Api.D_204, "查找不到对应的数据").get());
        }
    }

//    withdraw是不是记录太多了也不行，减少一些没有意义多余的记录

    /**
     * 测试通过，Jfinal3.0all里面有
     */
    public void tesddddt() {
        CacheUtils.putCache("testt", "asdfasfda");
        String resultCache = CacheUtils.getCache("testt");
    }
}
